package com.shanjupay.common.utilbak;

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.net.ssl.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Created by jinbang on 2019\11\20 0020.
 */
public class HttpsImageUtils {
    private static final int WIDTH = 200; // 二维码宽
    private static final int HEIGHT = 200; // 二维码高
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpsImageUtils.class);

    public static String getBase64ByImgUrl(String url){
        String suffix = url.substring(url.lastIndexOf(".") + 1);
        try {
            URL urls = new URL(url);
            ByteArrayOutputStream  baos = new ByteArrayOutputStream();
            Image image = Toolkit.getDefaultToolkit().getImage(urls);
            BufferedImage  biOut = toBufferedImage(image);
            ImageIO.write(biOut, suffix, baos);
            String base64Str = Base64Util.encode(baos.toByteArray());
            return base64Str;
        } catch (Exception e) {
            return "";
        }

    }

    public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment
                .getLocalGraphicsEnvironment();
        try {
            int transparency = Transparency.OPAQUE;
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null),
                    image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            bimage = new BufferedImage(image.getWidth(null),
                    image.getHeight(null), type);
        }
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return bimage;
    }
    /**
     * 通过图片的url获取图片的base64字符串
     * @param imgUrl    图片url
     * @param isResize  是否需要缩放
     * @return    返回图片base64的字符串
     */
    public static String image2Base64(String imgUrl,int isResize) {

        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;
        try{
            url = new URL(imgUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();
            is = httpUrl.getInputStream();
            outStream = new ByteArrayOutputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度，如果为-1，代表全部读取完毕

            int len = 0;
            //使用一个输入流从buffer里把数据读取出来
     /*       while( (len=is.read(buffer)) != -1 ){
                //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                outStream.write(buffer, 0, len);
            }*/

            String str = "";
            str = zoomTo300(is,300,300,isResize);
            return str;
            // 对字节数组Base64编码
            //return Base64Util.encode(outStream.toByteArray());

        }catch (Exception e) {
            e.printStackTrace();
        }

        finally{
            if(is != null)
            {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outStream != null)
            {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(httpUrl != null)
            {
                httpUrl.disconnect();
            }
        }
        return imgUrl;

    }
                /**
               * 根据文件流判断图片类型
               * @param fis
               * @return jpg/png/gif/bmp
               */
            public static String getPicType(InputStream is) {
            //读取文件的前几个字节来判断图片格式
                byte[] b = new byte[4];
            try {
                is.read(b, 0, b.length);
                String type = HexUtil.bytes2Hex(b).toUpperCase();
                    return type;
            } catch (IOException e) {
                 e.printStackTrace();
            }finally{
                if(is != null){
                    try {
                        is.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
            }
            return null;
    }

    /**
     * 按固定长宽进行缩放
     * @param is      输入流
     * @param width   指定长度
     * @param height  指定宽度
     * @throws Exception
     */
    public static String zoomImage(InputStream is, int width, int height) throws Exception {
        String str="";
        //读取图片
        BufferedImage bufImg = ImageIO.read(is);
        is.close();
        //获取缩放比例
        double wRatio = width * 1.0/ bufImg.getWidth();
        double hRatio = height * 1.0 / bufImg.getHeight();

        AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wRatio, hRatio), null);
        BufferedImage bufferedImage = ato.filter(bufImg, null);
        //写入缩减后的图片
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", outStream);
        byte b[] = outStream.toByteArray();//从流中获取数据数组。
        str = new Base64().encodeAsString(b);
        return str;
    }


    /**
     *  tiff 图片 转  JPG 图片
     * @param filePath   tiff文件路径
     */
/*    public static void tiffTurnJpg(String filePath){
        OutputStream ops = null;
        try {
            ops = new FileOutputStream("E:/A测试流/fk2.jpg");
            //文件存储输出流
            JPEGEncodeParam param = new JPEGEncodeParam();
            ImageEncoder image = ImageCodec.createImageEncoder("JPEG", ops, param); //指定输出格式
            //解析输出流进行输出
            image.encode(file);
            //关闭流
            ops.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("tiff转换jpg成功");
    }*/
    /**
     * 等比例缩放，以宽或高较大者达到指定长度为准
     * @param is      输入文件路径
     * @param width    指定宽
     * @param height   指定高
     * @param isResize 是否需要缩放
     */
    public static String zoomTo300(InputStream is,  Integer width, Integer height,int isResize) throws Exception{
        String str="";
        //读取图片
        BufferedImage bufImg = ImageIO.read(is);
        LOGGER.info("等比例缩放图片格式："+getPicType(is));
        if(bufImg==null){

        }
        is.close();

        int w0 = 300;
        int h0 = 268;
        w0 = bufImg.getWidth();
        h0 = bufImg.getHeight();
        boolean isTrans = false;
        if(isResize == 1){
            /*if(w0 > 1100 && h0 > 1000){
                isTrans = true;
            }*/
        }else {
            isTrans = true;
        }
        // 输出
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte b[] = null;
        if(isTrans){
            // 获取较大的一个缩放比率作为整体缩放比率
            double wRatio = 1.0 * width / w0;
            double hRatio = 1.0 * height / h0;
            double ratio = Math.min(wRatio, hRatio);
            // 缩放
            AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
            BufferedImage bufferedImage = ato.filter(bufImg, null);
            ImageIO.write(bufferedImage, "jpg", outStream);
            b = outStream.toByteArray();//从流中获取数据数组。
        }else {
            ImageIO.write(bufImg, "jpg", outStream);
            b = commpressPicCycle(outStream.toByteArray(),100,0.8);
        }

        LOGGER.info("图片大小："+b.length);
        str = new Base64().encodeAsString(b);
        return str;
    }

    private static byte[] commpressPicCycle(byte[] bytes, long desFileSize, double accuracy) throws IOException {
        // File srcFileJPG = new File(desPath);
        long srcFileSizeJPG = bytes.length;
        // 2、判断大小，如果小于500kb，不压缩；如果大于等于500kb，压缩
        if (srcFileSizeJPG <= desFileSize * 1024) {
            return bytes;
        }
        // 计算宽高
        BufferedImage bim = ImageIO.read(new ByteArrayInputStream(bytes));
        int srcWdith = bim.getWidth();
        int srcHeigth = bim.getHeight();
        int desWidth = new BigDecimal(srcWdith).multiply(
                new BigDecimal(accuracy)).intValue();
        int desHeight = new BigDecimal(srcHeigth).multiply(
                new BigDecimal(accuracy)).intValue();

        ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节输出流（写入到内存）
        Thumbnails.of(new ByteArrayInputStream(bytes)).size(desWidth, desHeight).outputQuality(accuracy).toOutputStream(baos);
        return commpressPicCycle(baos.toByteArray(), desFileSize, accuracy);
    }

    private static void trustAllHttpsCertificates() throws NoSuchAlgorithmException, KeyManagementException {
        TrustManager[] trustAllCerts = new TrustManager[1];
        trustAllCerts[0] = new TrustAllManager();
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

    private static class TrustAllManager implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
        }

        public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
        }
    }

    static {
        try {
            trustAllHttpsCertificates();
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String urlHostName, SSLSession session) {
                    return true;
                }
            });
        } catch (Exception e) {
        }
    }

}
